<?php
// ------------------------------------------------------------------------
// |@Author       : Jarmin <edshop@qq.com>
// |@----------------------------------------------------------------------
// |@Date         : 2023-06-24 20:15:17
// |@----------------------------------------------------------------------
// |@LastEditTime : 2023-12-06 11:13:35
// |@----------------------------------------------------------------------
// |@LastEditors  : Jarmin <jarmin@ladmin.cn>
// |@----------------------------------------------------------------------
// |@Description  : 
// |@----------------------------------------------------------------------
// |@FilePath     : Menu.php
// |@----------------------------------------------------------------------
// |@Copyright (c) 2023 http://www.ladmin.cn   All rights reserved. 
// ------------------------------------------------------------------------
namespace app\setting\logic;

use think\admin\Logic;

/**
 * 菜单逻辑类，用于实现菜单相关的业务逻辑操作。
 */
class Menu extends Logic
{
    /**
     * 根据条件查询菜单列表。
     * 如果 $data 中包含 name 字段，则返回名称包含指定字符串的菜单列表；
     * 否则返回全部菜单列表。菜单列表按 sort 字段递增排序。
     * @param array $data 查询条件。可以包含 name 字段，表示查询名称包含指定字符串的菜单列表。
     * @return array 菜单列表数组。
     */
    public function getList(array $data): array
    {
        // 根据查询条件 $data 组装 SQL 的 WHERE 子句
        $where = !empty($data['title']) ? [["title", "like", "%" . $data['title'] . "%"]] : [["id", ">", 0]];
        // 查询数据库，获取符合条件的所有菜单记录
        $menus = $this->modelSystemMenu->where($where)->order(['pid' => 'asc', 'id'=>'asc', 'sort' => 'asc'])->select()->toArray();
        // 遍历菜单数据列表，解析 api_list 字段为数组格式，并将解析后的结果赋值给对应的菜单数据。
        foreach ($menus as $key => $menu) {
            !empty($menu['api_list']) ? $menus[$key]['api_list'] = json_decode($menu['api_list'], true) : $menus[$key]['api_list'] = $menu['api_list'];
        }
        // 返回查询结果和执行状态信息
        return $this->json(SUCCESS, lang('menu.get_menu_list_success'), $menus);
    }

    /**
     * 保存菜单信息。如果 $data 中包含 id，则执行更新操作；否则执行添加操作。
     * @param array $data 菜单信息。必须包含 name、sort、status 等字段。
     * @return JsonResponse
     */
    public function saveMenu(array $data)
    {
        return $this->tryCatch(function () use ($data) {
            if (!empty($data['api_list']) && $data['type'] != 'button') {
                return $this->json(ERROR, lang('menu.type_select_error'));
            }
            $data['api_list'] = json_encode($data['api_list'] ?? []);
            if (!empty($data['id'])) {
                // 如果传入的 $data 中有 id ，则执行更新操作
                $this->modelSystemMenu->updateById($data['id'], $data);
                // 编辑成功，写入日志
                // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.menu_edit'), lang('log.edit_menu_info',['name'=>$data['title']]));
            } else {
                // 否则执行添加操作
                $data['id'] = $this->modelSystemMenu->add($data);
                // 创建成功，写入日志
                // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.menu_add'), lang('log.add_menu_info',['name'=>$data['title']]));
            }
            // 返回保存结果和菜单信息
            return $this->json(SUCCESS, lang('menu.save_menu_info_success'), $data);
        });
    }

    /**
     * 对菜单项进行排序
     * @param array $data 包含 dragid, dropid 和 droptype 等字段的数组
     * @return mixed 返回排序后的菜单项
     */
    public function sortMenu(array $data)
    {
        return $this->tryCatch(function () use ($data) {
            // 调用封装排序方法进行排序
            $result = $this->modelSystemMenu->updateMenuItemSort($data['dragid'], $data['dropid'], $data['droptype']);
            return $this->json(SUCCESS, lang('menu.update_menu_sort_success'), $result);
        });
    }

    /**
     * 以事务方式删除多个部门及其所有子孙部门。
     * @param array $data 待删除部门ID列表
     * @return JsonResponse
     * @throws \think\db\exception\PDOException
     * @throws \Throwable
     */
    public function deleteMenu(array $data)
    {
        return $this->tryCatch(function () use ($data) {
            // 找到所有待删除的节点和它们的所有子节点。
            $toDelete = $this->modelSystemMenu->whereIn('id', $data['ids'])->select();
            $toDeleteIds = array_column($toDelete->toArray(), 'id');
            foreach ($toDelete->toArray() as $item) {
                $toDeleteIds = array_merge($toDeleteIds, $this->getDescendantIds($this->modelSystemMenu, $item['id']));
            }
            // 删除所有待删除的节点和它们的所有子节点。
            $this->modelSystemMenu->deleteById($toDeleteIds);
            // 删除成功，写入日志
            // $this->serviceSystem->setLog(SUCCESS, 'info', lang('log.menu_delete'), lang('log.menu_delete_for', ['id' => implode(',', $toDeleteIds)]));
            // 返回删除成功的信息和状态
            return $this->json(SUCCESS, lang('menu.delete_menu_success'));
        });
    }
}
